package XmlUtils

import (
	"encoding/xml"
	"fmt"
	"strings"
	"frame/utils/FileUtils"
)

type Attribute struct {
	Name  string
	Value string
}

type Token struct {
	Name       string
	Type       string
	Attributes []Attribute
	Tokens     []Token
	Data       string
}

type Result struct {
	Root Token
}

func Parse(filecontent string, result *Result) (bool,error) {
	//计算起始index，去除<?指令和<!指令
	var idx_start = 0;
	for {
		if (filecontent[idx_start:idx_start+2] == "<?") {
			idx_start += strings.Index(filecontent, "\n") + 1
		} else if (filecontent[idx_start:idx_start+2] == "<!") {
			idx_start += strings.Index(filecontent, "\n") + 1
		} else {
			break
		}
	}
	var t xml.Token
	decoder := xml.NewDecoder(strings.NewReader(filecontent[idx_start:]))
	t, decerr := decoder.Token()
	if decerr != nil {
		//fmt.Println(decerr)
		return false,decerr
	}
	parse_token(decoder, t, &result.Root)
	//fmt.Println("result", result.Root)
	return true,nil
}

func parse_token(decoder *xml.Decoder, tt xml.Token, mytoken *Token) {
	token := tt.(xml.StartElement)
	name := token.Name.Local

	mytoken.Name = name
	mytoken.Type = "NODE"
	for _, attr := range token.Attr {
		attrName := attr.Name.Local
		attrValue := attr.Value
		attr := Attribute{Name: attrName, Value: attrValue}
		mytoken.Attributes = append(mytoken.Attributes, attr)
	}
	var t xml.Token
	var err error

	for t, err = decoder.Token(); err == nil; t, err = decoder.Token() {
		switch t.(type) {
		// 处理元素开始（标签）
		case xml.StartElement:
			mytoken.Tokens = append(mytoken.Tokens, Token{})
			parse_token(decoder, t, &mytoken.Tokens[len(mytoken.Tokens)-1])
			// 处理元素结束（标签）
		case xml.EndElement:
			return
		case xml.CharData:
			var dataToken = Token{}
			dataToken.Name="DATA"
			dataToken.Type="DATA"
			var chardata  = string([]byte(t.(xml.CharData)))
			dataToken.Data = chardata
			mytoken.Tokens = append(mytoken.Tokens, dataToken)
		default:
			return
		}
	}
}

func GetContentFromToken(token *Token)(string){
	var result = "";
	if(token.Type=="DATA"){
		return token.Data
	}
	if(token.Type=="NODE"){
		for _,v := range token.Tokens {
			result +=GetContentFromToken(&v)
		}
	}
	return result
}

func main() {
	var filecontent, err = FileUtils.ReadFile("D:/computer/go_workspace_sn/gdbc/TblSysDicMapper.xml")
	if (err != nil) {
		panic(err)
	}
	var result = Result{}
	if parseResult,err := Parse(filecontent,&result);!parseResult{
		panic(err)
	}
	fmt.Println("OK")
	fmt.Println(GetContentFromToken(&result.Root))
}